#pragma once
#include "user.hpp"
#include "linked_list.hpp"
#include "sql.hpp"
#include <cstdio>
#include <cassert>
#include <cstring>
#include <string>
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <sys/types.h>
#include <string>
using namespace std;
#define SIZE(a) (sizeof(a) / sizeof(a[0]))
typedef void (*sighandler_t)(int);
#define ARGS_CHECK(argc, num)                 \
    {                                         \
        if (argc != num)                      \
        {                                     \
            fprintf(stderr, "ARGS ERROR!\n"); \
            return -1;                        \
        }                                     \
    }
#define ERROR_CHECK(ret, num, msg) \
    {                              \
        if (ret == num)            \
        {                          \
            perror(msg);           \
            return -1;             \
        }                          \
    }
#define THREAD_ERROR_CHECK(ret, func)                        \
    {                                                        \
        if (ret != 0)                                        \
        {                                                    \
            fprintf(stderr, "%s:%s\n", func, strerror(ret)); \
        }                                                    \
    }
#define EVENT_ARR_SIZE 100
enum CmdType
{
    CMD_TYPE_PWD = 1,
    CMD_TYPE_LS,
    CMD_TYPE_CD,
    CMD_TYPE_MKDIR,
    CMD_TYPE_RMDIR,
    CMD_TYPE_PUTS,
    CMD_TYPE_GETS,
    CMD_TYPE_NOTCMD,
    // V1 用linux系统的文件中的信息模拟的用户假登陆
    //  TASK_LOGIN_SECTION1 = 100,
    //  TASK_LOGIN_SECTION1_RESP_OK,
    //  TASK_LOGIN_SECTION1_RESP_ERROR,
    //  TASK_LOGIN_SECTION2,
    //  TASK_LOGIN_SECTION2_RESP_OK,
    //  TASK_LOGIN_SECTION2_RESP_ERROR
    LOGIN_PRE = 100,
    LOGIN_NO,
    LOGIN_POK,
    LOGIN_Q,
    LOGIN_OK,
    REGISTER_PRE,
    REGISTER_NO,
    REGISTER_POK,
    REGISTER_Q,
    REGISTER_OK
};
struct Zhuce
{
    char name[30];
    char passward[100];
    char token[50];
};
struct train_t
{
    int len;
    CmdType type;
    char buff[1000];
};
struct task_t
{
    int peerfd;
    int epfd; // epoll的实例
    CmdType type;
    char data[1000];
    task_t *pNext;
};
struct task_queue_t
{
    task_t *pFront;
    task_t *pRear;
    int queueSize;
    int exit_flag;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
};
struct threadpool_t
{
    pthread_t *pthreads;
    int threadNum;
    task_queue_t queue;
};
void queueInit(task_queue_t *que);
void queueDestroy(task_queue_t *que);
int taskSize(task_queue_t *que);
int queueIsEmpty(task_queue_t *que);
void taskEnqueue(task_queue_t *que, task_t *ptask);
task_t *taskDequeue(task_queue_t *que);
void threadpoolInit(threadpool_t *threadpool, int num);
void threadpoolDestroy(threadpool_t *threadpool);
void threadpoolStart(threadpool_t *threadpool);
int tcpInit(const char *ip, const uint16_t port);
int epollAddReadFd(int epfd, int fd);
int epollDelReadFd(int epfd, int fd);
int recvn(int sockfd, void *buff, int len);
int sendn(int sockfd, const void *buff, int len);
int transferFile(int peerfd);
void threadpoolStop(threadpool_t *threadpool);
void handleMessage(int sockfd, int epfd, task_queue_t *queue);
void doTask(task_t *task);
void cdCommand(task_t *task);
void lsCommand(task_t *task);
void pwdCommand(task_t *task);
void mkdirCommand(task_t *task);
void rmdirCommand(task_t *task);
void notCommand(task_t *task);
void putsCommand(task_t *task);
void getsCommand(task_t *task);
void userLoginCheck1(task_t *task);
void userRegistCheck2(task_t *task);